// Package ginx
// Created by GoLand
// @User: lenora
// @Date: 2024/7/26
// @Time: 17:07

package ginx

import (
	"camp/microbook/pkg/logger"
	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"net/http"
	"strconv"
)

var (
	L      logger.Logger = logger.NewNoOpLogger()
	vector *prometheus.CounterVec
)

func InitCounter(opts prometheus.CounterOpts) {
	vector = prometheus.NewCounterVec(opts, []string{"code"})
	prometheus.MustRegister(vector)
}

// WrapBodyAndClaims
// @param bizFn 业务逻辑
// @param req
// @param uc
// @return gin.HandlerFunc
func WrapBodyAndClaims[Req any, Claims any](bizFn func(ctx *gin.Context, req Req, uc Claims) (ApiResponse, error)) gin.HandlerFunc {
	return func(context *gin.Context) {
		var req Req
		if err := context.Bind(&req); err != nil {
			L.Error("param error", logger.Error(err))
			webResp.InvalidParametersError(context)
			return
		}
		uc, ok := context.MustGet("user").(Claims)
		if !ok {
			L.Error("get user session failed")
			context.AbortWithStatus(http.StatusUnauthorized)
		}
		res, err := bizFn(context, req, uc)
		vector.WithLabelValues(strconv.Itoa(int(res.Code))).Inc()
		if err != nil {
			L.Error("execute logic failed", logger.Error(err))
		}
		context.JSON(http.StatusOK, res)
	}
}

func WrapBody[Req any](bizFn func(ctx *gin.Context, req Req) (ApiResponse, error)) gin.HandlerFunc {
	return func(context *gin.Context) {
		var req Req
		if err := context.Bind(&req); err != nil {
			L.Error("param error", logger.Error(err))
			webResp.InvalidParametersError(context)
			return
		}
		res, err := bizFn(context, req)
		vector.WithLabelValues(strconv.Itoa(int(res.Code))).Inc()
		if err != nil {
			L.Error("execute logic failed", logger.Error(err))
		}
		context.JSON(http.StatusOK, res)
	}
}

func WrapClaims[Claims any](bizFn func(ctx *gin.Context, uc Claims) (ApiResponse, error)) gin.HandlerFunc {
	return func(context *gin.Context) {
		uc, ok := context.MustGet("web").(Claims)
		if !ok {
			L.Error("get user session failed")
			context.AbortWithStatus(http.StatusUnauthorized)
		}
		res, err := bizFn(context, uc)
		vector.WithLabelValues(strconv.Itoa(int(res.Code))).Inc()
		if err != nil {
			L.Error("execute logic failed", logger.Error(err))
		}
		context.JSON(http.StatusOK, res)
	}
}
